package com.yuanbao.common.handler;

import com.yuanbao.base.enums.ResponseCodeEnum;
import com.yuanbao.base.response.Message;
import com.yuanbao.common.utils.RequestLogUtils;
import com.yuanbao.common.exception.ErrorCodeException;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

/**
 * 全局异常
 */
@ControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @Autowired
    private HttpServletRequest request;

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Message<String> handler(Exception e) {
        Message<String> result;
        if (e instanceof MethodArgumentNotValidException) {
            LOGGER.error("MethodArgumentNotValidException error:{}", ExceptionUtils.getStackTrace(e));
            BindingResult br = ((MethodArgumentNotValidException) e).getBindingResult();
            result = new Message<>(ResponseCodeEnum.INVALID_PARAM.getCode(), br.getFieldError().getField() + "字段填写有误：" + br.getFieldError().getDefaultMessage());
        } else if (e instanceof ErrorCodeException) {
            LOGGER.error("ErrorCodeException error:{}", ExceptionUtils.getStackTrace(e));
            result = new Message<>(((ErrorCodeException) e).getCode(), e.getMessage());
        } else {
            LOGGER.error("other error:{}", ExceptionUtils.getStackTrace(e));
            result = new Message<>(ResponseCodeEnum.UNKNOWN_ERROR.getCode(), e.getMessage());
        }
        RequestLogUtils.logRequestAndResponse(request, null, result);
        return result;
    }
}